Suomi

Opettele käyttämään JavaScriptin AbortControlleria fetch-pyyntöjen, ajastimien ja muiden asynkronisten operaatioiden tehokkaaseen peruuttamiseen.

JavaScript AbortController: Asynkronisten operaatioiden peruuttamisen hallinta

Nykyaikaisessa verkkokehityksessä asynkroniset operaatiot ovat kaikkialla. Datan hakeminen API:sta, ajastimien asettaminen ja käyttäjän vuorovaikutusten käsittely sisältävät usein koodia, joka suoritetaan itsenäisesti ja mahdollisesti pitkän ajan. On kuitenkin tilanteita, joissa sinun on peruutettava nämä operaatiot ennen niiden valmistumista. Tässä JavaScriptin AbortController-rajapinta tulee apuun. Se tarjoaa puhtaan ja tehokkaan tavan lähettää peruutuspyyntöjä DOM-operaatioille ja muille asynkronisille tehtäville.

Peruuttamisen tarpeen ymmärtäminen

Ennen teknisiin yksityiskohtiin sukeltamista ymmärretään, miksi asynkronisten operaatioiden peruuttaminen on tärkeää. Harkitse näitä yleisiä tilanteita:

AbortController ja AbortSignal esittelyssä

AbortController-rajapinta on suunniteltu ratkaisemaan asynkronisten operaatioiden peruuttamisen ongelma. Se koostuu kahdesta keskeisestä osasta:

Peruskäyttö: Fetch-pyyntöjen peruuttaminen

Aloitetaan yksinkertaisella esimerkillä fetch-pyynnön peruuttamisesta:


const controller = new AbortController();
const signal = controller.signal;

fetch('https://api.example.com/data', { signal })
  .then(response => {
    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }
    return response.json();
  })
  .then(data => {
    console.log('Data:', data);
  })
  .catch(error => {
    if (error.name === 'AbortError') {
      console.log('Fetch aborted');
    } else {
      console.error('Fetch error:', error);
    }
  });

// Fetch-pyynnön peruuttaminen:
controller.abort();

Selitys:

  1. Luomme AbortController-instanssin.
  2. Haemme siihen liittyvän AbortSignalin controller-objektista.
  3. Välitämme signal-objektin fetch-kutsun asetuksiin.
  4. Jos meidän on peruutettava pyyntö, kutsumme controller.abort().
  5. .catch()-lohkoon tarkistamme, onko virhe AbortError. Jos on, tiedämme, että pyyntö peruutettiin.

AbortErrorin käsittely

Kun controller.abort() kutsutaan, fetch-pyyntö hylätään AbortError-virheellä. On ratkaisevan tärkeää käsitellä tämä virhe asianmukaisesti koodissasi. Sen laiminlyönti voi johtaa käsittelemättömiin promise-hylkäyksiin ja odottamattomaan toimintaan.

Tässä on vankempi esimerkki virheenkäsittelyllä:


const controller = new AbortController();
const signal = controller.signal;

async function fetchData() {
  try {
    const response = await fetch('https://api.example.com/data', { signal });
    if (!response.ok) {
      throw new Error(`HTTP error! Status: ${response.status}`);
    }
    const data = await response.json();
    console.log('Data:', data);
    return data;
  } catch (error) {
    if (error.name === 'AbortError') {
      console.log('Fetch aborted');
      return null; // Tai heitä virhe käsiteltäväksi ylempänä
    } else {
      console.error('Fetch error:', error);
      throw error; // Heitä virhe uudelleen käsiteltäväksi ylempänä
    }
  }
}

fetchData();

// Fetch-pyynnön peruuttaminen:
controller.abort();

Parhaat käytännöt AbortErrorin käsittelyyn:

Ajastimien peruuttaminen AbortSignalilla

AbortSignal-objektia voidaan käyttää myös setTimeout- tai setInterval-funktioilla luotujen ajastimien peruuttamiseen. Tämä vaatii hieman enemmän manuaalista työtä, koska sisäänrakennetut ajastintoiminnot eivät suoraan tue AbortSignalia. Sinun on luotava mukautettu funktio, joka kuuntelee peruutuspyyntöä ja tyhjentää ajastimen, kun se laukeaa.


function cancellableTimeout(callback, delay, signal) {
  let timeoutId;

  const timeoutPromise = new Promise((resolve, reject) => {
    timeoutId = setTimeout(() => {
      resolve(callback());
    }, delay);

    signal.addEventListener('abort', () => {
      clearTimeout(timeoutId);
      reject(new Error('Timeout Aborted'));
    });
  });

  return timeoutPromise;
}

const controller = new AbortController();
const signal = controller.signal;


cancellableTimeout(() => {
  console.log('Timeout executed');
}, 2000, signal)
.then(() => console.log("Timeout finished successfully"))
.catch(err => console.log(err));

// Ajastimen peruuttaminen:
controller.abort();

Selitys:

  1. cancellableTimeout-funktio ottaa argumentteina takaisinkutsun, viiveen ja AbortSignalin.
  2. Se asettaa setTimeout-ajastimen ja tallentaa sen tunnisteen.
  3. Se lisää tapahtumakuuntelijan AbortSignaliin, joka kuuntelee abort-tapahtumaa.
  4. Kun abort-tapahtuma laukeaa, tapahtumakuuntelija tyhjentää ajastimen ja hylkää promisen.

Tapahtumakuuntelijoiden peruuttaminen

Samoin kuin ajastimien kanssa, voit käyttää AbortSignalia tapahtumakuuntelijoiden peruuttamiseen. Tämä on erityisen hyödyllistä, kun haluat poistaa tapahtumakuuntelijat, jotka liittyvät purettavaan komponenttiin.


const controller = new AbortController();
const signal = controller.signal;

const button = document.getElementById('myButton');

button.addEventListener('click', () => {
  console.log('Button clicked!');
}, { signal });

// Tapahtumakuuntelijan peruuttaminen:
controller.abort();

Selitys:

  1. Välitämme signal-objektin addEventListener-metodin asetuksissa.
  2. Kun controller.abort() kutsutaan, tapahtumakuuntelija poistetaan automaattisesti.

AbortController React-komponenteissa

Reactissa voit käyttää AbortControlleria peruuttaaksesi asynkronisia operaatioita komponentin purkamisen yhteydessä. Tämä on välttämätöntä muistivuotojen ja purkamattomien komponenttien päivittämisen aiheuttamien virheiden estämiseksi. Tässä on esimerkki useEffect-hookin avulla:


import React, { useState, useEffect } from 'react';

function MyComponent() {
  const [data, setData] = useState(null);

  useEffect(() => {
    const controller = new AbortController();
    const signal = controller.signal;

    async function fetchData() {
      try {
        const response = await fetch('https://api.example.com/data', { signal });
        if (!response.ok) {
          throw new Error(`HTTP error! Status: ${response.status}`);
        }
        const data = await response.json();
        setData(data);
      } catch (error) {
        if (error.name === 'AbortError') {
          console.log('Fetch aborted');
        } else {
          console.error('Fetch error:', error);
        }
      }
    }

    fetchData();

    return () => {
      controller.abort(); // Peruuta fetch-pyyntö komponentin purkamisen yhteydessä
    };
  }, []); // Tyhjä riippuvuuslista varmistaa, että tämä efekti suoritetaan vain kerran komponentin latautuessa

  return (
    
{data ? (

Data: {JSON.stringify(data)}

) : (

Loading...

)}
); } export default MyComponent;

Selitys:

  1. Luomme AbortControllerin useEffect-hookin sisälle.
  2. Välitämme signal-objektin fetch-pyyntöön.
  3. Palautamme siivousfunktion useEffect-hookista. Tämä funktio kutsutaan komponentin purkamisen yhteydessä.
  4. Siivousfunktion sisällä kutsumme controller.abort() peruuttaaksemme fetch-pyynnön.

Edistyneet käyttötapaukset

AbortSignalien ketjuttaminen

Joskus saatat haluta ketjuttaa useita AbortSignal-objekteja yhteen. Esimerkiksi ylätason komponentti, jonka on peruutettava ala-komponenttien operaatiot. Voit saavuttaa tämän luomalla uuden AbortControllerin ja välittämällä sen signaalin sekä ylätason että ala-komponenteille.

AbortControllerin käyttäminen kolmannen osapuolen kirjastojen kanssa

Jos käytät kolmannen osapuolen kirjastoa, joka ei suoraan tue AbortSignalia, saatat joutua mukauttamaan koodiasi toimiakseen kirjaston peruutusmekanismin kanssa. Tämä voi sisältää kirjaston asynkronisten funktioiden käärimisen omiin funktioihisi, jotka käsittelevät AbortSignalia.

AbortControllerin käytön edut

Selaimen yhteensopivuus

AbortController on laajalti tuettu moderneissa selaimissa, kuten Chromessa, Firefoxissa, Safarissa ja Edgessä. Voit tarkistaa yhteensopivuustaulukon MDN Web Docsista saadaksesi viimeisimmät tiedot.

Polyfillit

Vanhemmille selaimille, jotka eivät natiivisti tue AbortControlleria, voit käyttää polyfilliä. Polyfill on koodinpätkä, joka tarjoaa uudemman ominaisuuden toiminnallisuuden vanhemmissa selaimissa. Saatavilla on useita AbortController-polyfilliä verkossa.

Yhteenveto

AbortController-rajapinta on tehokas työkalu asynkronisten operaatioiden hallintaan JavaScriptissä. Käyttämällä AbortControlleria voit kirjoittaa puhtaampaa, suorituskykyisempää ja vankempaa koodia, joka käsittelee peruuttamisen tyylikkäästi. Olipa kyse sitten datan hakemisesta API:sta, ajastimien asettamisesta tai tapahtumakuuntelijoiden hallinnasta, AbortController voi auttaa sinua parantamaan verkkosovellustesi yleistä laatua.

Lisätietoja